package jdk.thread.lock;

import serializable.User;

import java.util.concurrent.locks.LockSupport;


/**
 * LockSupport,主要是为了阻塞和唤醒线程用的，主要方法：park(), unpark();
 * 和wait/notify有什么区别？
 * 1）wait/notify都是Object中的方法，调用这两个方法前必须先获取锁对象，但是park/unpark不需要！
 * 2）notify只能随机选择一个线程唤醒，unpark却可以唤醒制定线程！！
 * park -> 停车！
 *
 * LockSupport Class
 * public static void park(Object blocker); // 暂停当前线程并设置阻塞者
 * public static void parkNanos(Object blocker, long nanos); // 暂停当前线程，不过有超时时间的限制
 * public static void parkUntil(Object blocker, long deadline); // 暂停当前线程，直到某个时间
 * public static void park(); // 无期限暂停当前线程
 * public static void parkNanos(long nanos); // 暂停当前线程，不过有超时时间的限制
 * public static void parkUntil(long deadline); // 暂停当前线程，直到某个时间
 * public static void unpark(Thread thread); // 恢复当前线程
 * public static Object getBlocker(Thread t);   //根据线程获取阻塞者
 */
public class LockSupportTest {


    public static void main(String[] args) throws InterruptedException {


        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程1开始了。。。。");
                LockSupport.park("luobinjie");
                System.out.println("线程1结束了。。。。");
            }
        });

        thread1.start();

        Thread.sleep(1000l);

        //park后，线程的状态是WAITING， 但wait()后的WAITING
        System.out.println("线程1的状态："+thread1.getState());
        //使用park()时，getBlocker()==null;
        System.out.println("线程1的Blocker： "+LockSupport.getBlocker(thread1));
        LockSupport.unpark(thread1);
    }


    /*
     * blocker是用来记录线程被阻塞时被谁阻塞的。
     * 用于线程监控和分析工具来定位原因的。
     * setBlocker(t, blocker)方法的作用是记录t线程是被broker阻塞的。
     * 因此我们只关注最核心的方法，
     * 也就是UNSAFE.park(false, 0L)。
     *
     *
     * csdn::
     * t1内部有休眠1s的操作，所以unpark肯定先于park的调用，但是t1最终仍然可以完结。这是因为park和unpark会对每个线程维持一个许可（boolean值）
        unpark调用时，如果当前线程还未进入park，则许可为true
        park调用时，判断许可是否为true，如果是true，则继续往下执行；如果是false，则等待，直到许可为true
        *
        * blocker的作用是在dump线程的时候看到阻塞对象的信息

     */
}
